import Vue from 'vue'
import { ipcRenderer } from 'electron'
import types from '../mutation-types'
import {
  fetchNotifications,
  setNoticeRead,
  getUserMessages,
  setUserMessageRead
} from '@/api'
import { getNoticeDiff, notifyNotification } from '@/utils'

const state = {
  notifyStatus: true,
  atmefilters: [
    { label: '未读', value: 'unread' },
    { label: '所有', value: 'all' }
  ],
  atmefiltered: 'unread',
  eventFilters: [
    { label: '未读', value: 'unread' },
    { label: '我参与的', value: 'participating' },
    { label: '所有', value: 'all' }
  ],
  eventFiltered: 'unread',
  notifications: {
    atme: {
      list: [],
      total_count: 0,
      current_page: 1,
      loading: false
    },
    event: {
      list: [],
      total_count: 0,
      current_page: 1,
      loading: false
    },
    userMessage: {
      list: [],
      total_count: 0,
      current_page: 1,
      loading: false
    }
  },
  firstPages: {
    atme: {
      list: []
    },
    event: {
      list: []
    },
    userMessage: {
      list: []
    }
  }
}

const getters = {
  atmeNotice (state) {
    return state.notifications.atme
  },

  userMessage (state) {
    return state.notifications.userMessage
  },

  eventNotice (state) {
    return state.notifications.event
  }
}

const getType = (originalType) => {
  let type = 'atme'
  if (originalType === 'user_message') {
    type = 'userMessage'
  } else if (originalType === 'event') {
    type = 'event'
  }
  return type
}

const mutations = {
  [types.SET_NOTIFICATIONS] (state, { type, data }) {
    data = Object.assign({ loading: false }, data)
    Vue.set(state.notifications, type, data)
  },
  [types.SET_NOTICE_READ] (state, { id, type }) {
    state.notifications[type].list.some((notice, index) => {
      if (notice.id === id) {
        notice.unread = false
        return true
      }
    })
  },
  [types.SET_USER_MESSAGE_READ] (state, { id }) {
    state.notifications['userMessage'].list.some((notice, index) => {
      if (notice.id === id) {
        notice.unread = false
        return true
      }
    })
  },
  [types.SET_NOTICE_LOADING] (state, { type, value }) {
    state.notifications[type].loading = value
  },
  [types.SET_FIRST_PAGE] (state, { type, data }) {
    state.firstPages[type] = data
  },
  [types.SET_EVENT_FILTERED] (state, value) {
    state.eventFiltered = value
  },
  [types.SET_AT_ME_FILTERED] (state, value) {
    state.atmefiltered = value
  },
  [types.NOTIFY_STATUE_TOGGLE] (state) {
    state.notifyStatus = !state.notifyStatus
  }
}

const actions = {
  async fetchNotifications ({ commit }, params = {}) {
    const type = getType(params.type)
    commit(types.SET_NOTICE_LOADING, { type, value: true })
    const data = await fetchNotifications(params)
    commit(types.SET_NOTIFICATIONS, {
      type,
      data: { current_page: params.page || 1, loading: false, ...data }
    })
  },

  async setNoticeRead ({ commit }, { id, type }) {
    await setNoticeRead(id)
    commit(types.SET_NOTICE_READ, { id, type })
  },

  async setUserMessageRead ({ commit }, { id }) {
    await setUserMessageRead(id)
    commit(types.SET_USER_MESSAGE_READ, { id })
  },

  async fetchUserMessages ({ commit }, params = {}) {
    commit(types.SET_NOTICE_LOADING, { type: 'userMessage', value: true })
    const data = await getUserMessages(params)
    commit(types.SET_NOTIFICATIONS, {
      type: 'userMessage',
      data: {
        current_page: params.page || 1,
        loading: false,
        ...data
      }
    })
  },

  async setFirstPageData ({ commit }, datas) {
    Object.keys(datas).forEach(type => {
      commit(types.SET_FIRST_PAGE, {
        type,
        data: datas[type]
      })
    })
  },

  async fetchNewDataByDiff ({ dispatch, rootState, state }, datas = {}) {
    Object.keys(datas).forEach(type => {
      const filtered = state[`${type}Filtered`]
      // 若某 tab 通知有更新，且当前正在该 tab 下，且在第一页，则拉取新数据
      if (
        type === rootState.currentTab &&
        state.notifications[type].current_page === 1 &&
        datas[type].length
      ) {
        if (type === 'userMessage') {
          dispatch('fetchUserMessages')
        } else {
          dispatch('fetchNotifications', {
            unread: filtered === 'unread',
            participating: filtered === 'participating'
          })
        }
      }
    })
  },

  async fetchFirstPage ({ dispatch }, { type }) {
    const data = await fetchNotifications({ type, unread: true })
    type = getType(type)
    dispatch('setFirstPageData', {
      [type]: data
    })
  },

  async fetchUserMessageFirstPage ({ dispatch }) {
    const data = await getUserMessages({ unread: true })
    dispatch('setFirstPageData', {
      'userMessage': data
    })
  },

  async fetchAllFirstPage ({ dispatch }) {
    let [refererData, eventData, userMessageData] = await Promise.all([
      fetchNotifications({ type: 'referer' }),
      fetchNotifications({ type: 'event' }),
      getUserMessages()
    ])
    dispatch('setFirstPageData', {
      'atme': refererData,
      'event': eventData,
      'userMessage': userMessageData
    })
  },

  async notifyNewNotification ({ state, dispatch }) {
    let [refererData, eventData, userMessageData] = await Promise.all([
      fetchNotifications({ type: 'referer' }),
      fetchNotifications({ type: 'event' }),
      getUserMessages()
    ])
    let refererDiff = getNoticeDiff(state.firstPages[getType('referer')], refererData)
    let eventDiff = getNoticeDiff(state.firstPages[getType('event')], eventData)
    let userMessageDiff = getNoticeDiff(state.firstPages[getType('user_message')], userMessageData)

    notifyNotification(refererDiff, eventDiff, userMessageDiff)
    dispatch('fetchNewDataByDiff', {
      'atme': refererData,
      'event': eventData,
      'userMessage': userMessageData
    })
    dispatch('setFirstPageData', {
      'atme': refererData,
      'event': eventData,
      'userMessage': userMessageData
    })
  },

  setEventFiltered ({ commit }, value) {
    commit(types.SET_EVENT_FILTERED, value)
  },

  setAtMeFiltered ({ commit }, value) {
    commit(types.SET_AT_ME_FILTERED, value)
  },

  toggleNotifyStatus ({ state, commit }) {
    commit(types.NOTIFY_STATUE_TOGGLE)
    ipcRenderer.send('set-tray-icon', state.notifyStatus ? 'notify' : 'no-notify')
  }
}

export default {
  state,
  mutations,
  actions,
  getters
}
